/* 
 * File:   Belief.h
 * Author: Hadrien
 *
 * Created on 10 juillet 2012, 15:18
 */

#ifndef BELIEF_H
#define	BELIEF_H
#include <map>
#include <vector>
#include <iostream>

template<typename SUPERSTATE>
class Belief {
public:
    typedef SUPERSTATE super_state_t;

    Belief() {

    }

    virtual ~Belief() {

    }

    //Don't create a cell in the hashmap if the probability associated to the state is null

    double get(const super_state_t& state) const {
        map_const_it it;
        it = m_probabilities.find(state);
        if (it == m_probabilities.end())
            return 0;
        else
            return it->second;
    }

    //Create a cell in the hashmap if the probability associated to the state is null
    //Use this method to assign a new probability

    double& set(const super_state_t& state, double value) {
        if (value > 0)
            m_probabilities[state] = value;
        else
            m_probabilities.erase(state);
    }

    std::vector<super_state_t> getStates() const {
        std::vector<super_state_t> Sb;
        for (map_const_it it = m_probabilities.begin(); it != m_probabilities.end(); ++it) {
            Sb.push_back(it->first);
        }
        return Sb;
    }
    
    void normalize(const double& sum) {
        if(sum>0)
        {
            for (map_it it = m_probabilities.begin(); it != m_probabilities.end(); ++it) {
                it->second = it->second/sum;
            }
        }
    }
    template <typename SSTATE>
    friend std::ostream& operator<< (std::ostream &out, const Belief<SSTATE> &b);
private:
    typedef typename std::map<super_state_t, double> map;
    typedef typename map::const_iterator map_const_it;
    typedef typename map::iterator map_it;
    map m_probabilities;
};

template <typename SSTATE>
std::ostream& operator<< (std::ostream &out, const Belief<SSTATE> &b){
    for (typename Belief<SSTATE>::map_const_it it = b.m_probabilities.begin(); it != b.m_probabilities.end(); ++it) {
        out << "Prob:" << (it->second) << ", State: " << (it->first) << std::endl;
    }
    return out;
}
#endif	/* BELIEF_H */

